import mongodbHandle from '../handle/mongodbHandle'
import sessionHandle from '../handle/sessionHandle'
import routes from './route'
var ObjectId = require('mongodb').ObjectId;
var utility = require("utility");
import app from '../app'
import * as moment from 'moment'
const jwt = require('jsonwebtoken');

import utils from '../core/utils'
import gameUtils from 'js/core/gameUtils';
import redisHandle from 'src/handle/redisHandle';
import { base64 } from 'src/core/enco';
import { md5 } from 'js-md5';
import { PlayerModel } from 'js/model/playerModel';
import playerSessionHandle from 'src/handle/playerSessionHandle';

routes.setUserNotLogin('userRegister', [
    ['name', 'string'],
    ['pwd', 'string'],
    ['phone', 'string', false]
], async (msg) => {
    let name = msg.name
    let pwd = msg.pwd
    if (name.length > 30 || pwd.length > 30) {
        return { err: 1 }
    }
    let doc = await mongodbHandle.userDao.findOne({ name: name })
    if (doc) {
        return { err: 0, data: null, code: 1 }
    } else {
        await mongodbHandle.userDao.newAndSave(name, pwd, msg.phone || 'android')
        return { err: 0 }
    }
})

routes.setLogin('copyPlayer', [
    ['id', 'string']
], async (msg) => {
    if (app.env == 'demo' || app.env == 'dev') {
        let doc = await mongodbHandle.playerDaoTest.findOne({
            id: msg.id,
        })
        if (doc) {
            return { err: 0, data: doc.playerData }
        } else {
            return { err: 0 }
        }
    } else {
        return { err: 0 }
    }

})

routes.setLogin('getBakPlayer', [
    ['pid', 'string'],
    ['index', 'number']
], async (msg) => {
    if (app.env == 'demo' || app.env == 'dev') {
        let doc = await mongodbHandle.playerBakDaoTest.findOne({
            pID: msg.pid,
        }, {
            ['playerData' + msg.index]: 1
        })
        if (doc) {
            return { err: 0, data: doc }
        } else {
            return { err: 0 }
        }
    } else {
        return { err: 0 }
    }

})

routes.setUserNotLogin('userLogin', [
    ['name', 'string'],
    ['pwd', 'string']
], async (msg) => {
    let name = msg.name
    let pwd = msg.pwd
    let doc = await mongodbHandle.userDao.findOne({
        name: name,
        pwd: pwd
    })
    if (doc) {
        let token = jwt.sign({
            uID: doc._id
        }, "secretkey", {
            expiresIn: '2day'
        })
        let str = await redisHandle.get(app.config.gameName + 'gameSet')
        return {
            err: 0, data: {
                gameClientConfig: str,
                token: token,
                serverID: doc.serverID
            }
        }
    } else {

        return { err: 0, data: null, code: 1 }
    }
})

routes.setUserNotLogin('leUserLogin', [
    ['name', 'string'],
], async (msg) => {
    let name = msg.name
    let pwd = 'le' + name
    let doc = await mongodbHandle.userDao.findOne({
        name: name, pwd
    })
    if (!doc) {
        await mongodbHandle.userDao.newAndSave(name, pwd, false)
        doc = await mongodbHandle.userDao.findOne({
            name: name, pwd
        })
    }
    if (doc) {
        let token = jwt.sign({
            uID: doc._id
        }, "secretkey", {
            expiresIn: '2day'
        })
        let str = await redisHandle.get(app.config.gameName + 'gameSet')
        return {
            err: 0, data: {
                gameClientConfig: str,
                token: token,
                serverID: doc.serverID
            }
        }
    } else {
        return { err: 0, data: null, code: 1 }
    }
})


routes.setNotLogin('getServerList', [], async (msg, session) => {
    let docs = await mongodbHandle.serverDao.find({})
    return { err: 0, data: docs }
})

routes.setNotLogin('getPlayers', [
    ['serverID', 'number'],
], async (msg, session, cb) => {
    let docs = await mongodbHandle.playerDao.find({
        uID: session.uID,
        currentServerID: msg.serverID
    })
    if (docs) {
        let data = docs.map(item => {
            return {
                id: item._id,
                name: item.name,
            }
        })
        return { err: 0, data: data }
    } else {
        return { err: 0, data: null }
    }
})

routes.setNotLogin('playerRegister', [
    ['serverID', 'number'],
    ['data', 'object'],
], async (msg, token, cb) => {
    let {
        serverID,
        data
    } = msg

    let doc = await mongodbHandle.playerDao.findOne({
        uID: token.uID,
        currentServerID: serverID,
    })
    if (doc) {
        return { err: 0, data: null, code: 1 }
    } else {
        let player = new PlayerModel(data)
        let doc = await mongodbHandle.serverDao.findOne({
            serverID: serverID,
            active: true,
        })
        if (doc) {
            if (doc.time > new Date().getTime()) {
                return { err: 0, data: null, code: 2 }
            } else {
                let res = await mongodbHandle.playerDao.newAndSave(token.uID, doc.newServerID, player, false)
                return { err: 0 }
            }
        } else {
            return { err: 0, code: 3 }
        }
    }
})

routes.setNotLogin('playerLogin', [
    ['serverID', 'number'],
    ['index', 'number']
], async (msg, token, cb) => {
    let {
        serverID,
        index
    } = msg
    let doc = await mongodbHandle.serverDao.findOne({
        serverID: serverID,
    })

    if (doc) {
        let newServerID = doc.newServerID
        let docs = await mongodbHandle.playerDao.find({
            uID: token.uID,
            currentServerID: newServerID,
        })
        if (docs) {
            let res = docs[index]
            if (res) {
                let pID = res._id.toString();
                let session = await sessionHandle.addSession(pID, token.uID, res.name)
                session.pIndex = index
                session.serverID = newServerID
                sessionHandle.updateSession(session.pID, session)
                let newToken = jwt.sign({
                    uID: token.uID,
                    pID: pID,
                    serverID: newServerID,
                    sessionKey: session.sessionKey
                }, "secretkey", {
                    expiresIn: '2day'
                })

                //保存最近登录的服务器信息
                mongodbHandle.userDao.updateOne({
                    _id: ObjectId(token.uID)
                }, {
                    $set: {
                        serverID: newServerID
                    }
                })



                return { err: 0, data: newToken, code: 0 }
            } else {
                return { err: 1 }
            }
        } else {
            return { err: 0, data: null }
        }
    } else {
        return { err: 1 }
    }
})

routes.setLogin('getPlayer', [], async (msg, session, cb) => {
    let doc = await mongodbHandle.playerDao.findOne({
        _id: ObjectId(session.pID)
    })
    let serverdoc = await mongodbHandle.serverDao.findOne({ serverID: session.serverID })
    if (doc) {
        let player = doc
        player.version = app.version
        let str = await redisHandle.get(app.config.gameName + 'gameSet')
        let userData = await mongodbHandle.userDao.findOne({
            _id: ObjectId(session.uID)
        })
        if (userData) {
            player.hidePay = userData.hidePay
        }
        let clientplayer = {
            _id: player._id.toString(),
            id: player.id,
            playerData: player.playerData,
            chargeMoney: player.chargeMoney,
            loginTime: player.loginTime,
            uID: player.uID,
            name: player.name,
            originServerID: player.originServerID,
            currentServerID: player.currentServerID,
            vipTime: player.vipTime,
            cheat: player.cheat,
        }

        session.isClientLocal = false
        sessionHandle.updateSession(session.pID, session)
        return { err: 0, data: { player: clientplayer, gameClientConfig: str, isLocal: session.isClientLocal,  serverTime: serverdoc ? serverdoc.time : new Date().getTime() } }
    } else {
        return { err: 0, data: null }
    }
})

routes.setLogin('getPlayer2', [
    ['did', 'string']
], async (msg, session, cb) => {
    let {did} = msg
    await playerSessionHandle.savePlayer(session.pID)
    let doc = await mongodbHandle.playerDao.findOne({
        // _id: ObjectId('665dbeb1ea39080bf18e75f8')
        _id: ObjectId(session.pID)
    })
    let serverdoc = await mongodbHandle.serverDao.findOne({ serverID: session.serverID })
    if (doc && !doc.cheat) {
        let player = doc
        player.version = app.version
        let str = await redisHandle.get(app.config.gameName + 'gameSet')
        let userData = await mongodbHandle.userDao.findOne({
            _id: ObjectId(session.uID)
        })
        let clientplayer = {
            _id: player._id.toString(),
            id: player.id,
            playerData: player.playerData,
            saveKey: player.saveKey,
            chargeMoney: player.chargeMoney,
            loginTime: player.loginTime,
            uID: player.uID,
            name: player.name,
            originServerID: player.originServerID,
            currentServerID: player.currentServerID,
            vipTime: player.vipTime,
            longVip: player.longVip,
            newUserGift: player.newUserGift,
            did,
        }
        session.isClientLocal = false
        // if (did == doc.did || doc.phone == 'android') {
        //     session.isClientLocal = true
        // }
        sessionHandle.updateSession(session.pID, session)
        
        return { err: 0, data: { player: clientplayer, gameClientConfig: str, isLocal: session.isClientLocal, serverTime: serverdoc ? serverdoc.time : new Date().getTime() } }
    } else {
        return { err: 0, data: null }
    }
})

routes.setLogin('addPlayerCheat', [], async (msg, session, cb) => {
    let doc = await mongodbHandle.playerDao.findOne({
        _id: ObjectId(session.pID)
    })
    if (doc) {
        // if ((doc.cheatTimes || 0) > 3) {
        //     await mongodbHandle.playerDao.updateOne({
        //         _id: ObjectId(session.pID),
        //     }, {
        //         $set: {
        //             cheat: true
        //         }
        //     })
        //     return { err: 0 }
        // } else {
        await mongodbHandle.playerDao.updateOne({
            _id: ObjectId(session.pID),
        }, {
            $set: {
                cheatTimes: (doc.cheatTimes || 0) + 1
            }
        })
        return { err: 0 }
        // }
    }
    return { err: 1 }
})

routes.setLogin('getPlayerInfo', [], async (msg, session, cb) => {
    let doc = await mongodbHandle.playerDao.findOne({
        _id: ObjectId(session.pID)
    })
    if (doc) {
        let player = doc
        player.version = app.version
        let str = await redisHandle.get(app.config.gameName + 'gameSet')
        delete player.playerData
        return { err: 0, data: { player: player, gameClientConfig: str } }
    } else {
        return { err: 0, data: null }
    }
})

routes.setLogin('save', [
    ['data', 'string'],
    ['k', 'string']
], async (msg, session, cb) => {
    if(session.isClientLocal ){
        return { err: 110 }
    }
   
    // let mdhmac = md5.hmac('wuxia', msg.data)
    // if (mdhmac !== msg.k) {
    //     console.log("save", mdhmac, msg.k, session.pID)
    //     return { err: 2 }
    // }
    // let data = JSON.parse(base64.decode(msg.data))
    // if (data.id !== session.pID) {
    //     return { err: 5, data: null }
    // }
    // let player: PlayerModel = data

    // if (app.env == "pro" && data.version && Number(data.version) < 1.36) {
    //     // return {err: 3}
    // }
    // if (!data.v && data.v < 101) {
    //     return { err: 4 }
    // }
    // let doc = await mongodbHandle.playerDao.findOne({
    //     _id: ObjectId(session.pID),
    // })

    // if (doc) {
    //     let time = new Date().getTime()
    //     if (doc.bakTime == 0 || doc.bakTime == null || (doc.bakTime + 1 * 60 * 60 * 1000) < time) {
    //         doc.bakTime = time
    //         let hour = 'hour' + moment().hour()
    //         let playerData = 'playerData' + moment().hour()
    //         await mongodbHandle.playerBakDao.updateOne({
    //             pID: session.pID
    //         }, {
    //             $set: {
    //                 time: moment().valueOf(),
    //                 [hour]: moment().valueOf(),
    //                 [playerData]: player
    //             }
    //         }, { upsert: true })
    //     }

    //     doc.playerData = player
    //     let mapProgressMax = doc.mapProgressMax || 0

    //     if (player && player.baseInfo) {
    //         mapProgressMax = player.baseInfo.mapProgressMax
    //     }
    //     let totalPower = doc.totalPower || 0
    //     if (player && player.baseInfo.maxPower) {
    //         totalPower = player.baseInfo.maxPower
    //     }
    //     let abyssProgress = doc.abyssProgress || 0
    //     if (player && player.SoulMatrix.abyssProgress) {
    //         abyssProgress = player.SoulMatrix.abyssProgress
    //     }
    //     let weekDayIndex = doc.weekDayIndex || 0
    //     if (player && player.baseInfo.weekDayIndex) {
    //         weekDayIndex = player.baseInfo.weekDayIndex
    //     }
    //     await mongodbHandle.playerDao.updateOne({
    //         _id: ObjectId(session.pID),
    //     }, {
    //         $set: {
    //             playerData: player,
    //             loginTime: time,
    //             totalPower: totalPower,
    //             mapProgressMax: mapProgressMax,
    //             abyssProgress: abyssProgress,
    //             weekDayIndex: weekDayIndex,
    //             phone: doc.phone || 'android',
    //             saveKey: msg.k,
    //             saveData: msg.data
    //         }
    //     })
    //     return { err: 0 }
    // } else {
    //     return { err: 1 }
    // }
})



routes.setLogin('save1', [
    ['data', 'string'],
    ['k', 'string']
], async (msg, session, cb) => {
    if(session.isClientLocal ){
        return { err: 110 }
    }
    let mdhmac = md5.hmac(session.pID, msg.data)
    if (mdhmac !== msg.k) {
        return { err: 2 }
    }
    let data = JSON.parse(base64.decode(msg.data))
    if (data.id !== session.pID) {
        return { err: 5, data: null }
    }
    // let player: PlayerModel = data
    
    return { err: 0, code: 0 }
    // if (app.env == "pro" && data.version && Number(data.version) < 1.128) {
    //     return { err: 3 }
    // }
    // if (!data.v && data.v < 106) {
    //     return { err: 3 }
    // }
    // if (!data.treasureInfo || data.treasureInfo.treasurePower != 1) {
    //     let doc = await mongodbHandle.versionCheatDao.findOne({ pID: session.pID })
    //     if (doc) {
    //         if (doc.times >= 1) {
    //             await mongodbHandle.playerDao.updateOne({ _id: ObjectId(session.pID) }, {
    //                 $set: {
    //                     cheat: true
    //                 }
    //             })
    //             await mongodbHandle.cheatDao.newAndSave3(doc.uID, doc._id.toString(), 'version', 1)
    //             return { err: 0, code: 2 }
    //         } else {
    //             await mongodbHandle.versionCheatDao.updateOne({ pID: session.pID }, {
    //                 $set: {
    //                     times: (doc.times || 0) + 1
    //                 }
    //             })
    //         }
    //     } else {
    //         await mongodbHandle.versionCheatDao.newAndSave(session.pID, data)
    //     }
    //     return { err: 3 }
    // }
    // let doc = await mongodbHandle.playerDao.findOne({
    //     _id: ObjectId(session.pID),
    // })
    // if (doc && !doc.cheat) {
    //     let time = new Date().getTime()
    //     if (doc.bakTime == 0 || doc.bakTime == null || (doc.bakTime + 1 * 60 * 60 * 1000) < time) {
    //         doc.bakTime = time
    //         let hour = 'hour' + moment().hour()
    //         let playerData = 'playerData' + moment().hour()
    //         await mongodbHandle.playerBakDao.updateOne({
    //             pID: session.pID
    //         }, {
    //             $set: {
    //                 time: moment().valueOf(),
    //                 [hour]: moment().valueOf(),
    //                 [playerData]: player
    //             }
    //         }, { upsert: true })
    //     }

    //     doc.playerData = player
    //     let mapProgressMax = doc.mapProgressMax || 0

    //     if (player && player.baseInfo) {
    //         mapProgressMax = player.baseInfo.mapProgressMax
    //     }

    //     if (doc.chargeMoney > player.baseInfo.chargeMoney) {
    //         doc.playerData.baseInfo.chargeMoney = doc.chargeMoney
    //     }
    //     let totalPower = doc.totalPower || 0
    //     if (player && player.totalPower) {
    //         totalPower = player.totalPower
    //     }
    //     let deepProgress = doc.deepProgress || 0
    //     if (player && player.deepInfo) {
    //         deepProgress = player.deepInfo.progress
    //     }
    //     let weekDayIndex = doc.weekDayIndex || 0
    //     if (player && player.baseInfo.weekDayIndex) {
    //         weekDayIndex = player.baseInfo.weekDayIndex
    //     }
    //     let nightProgress = doc.nightProgress || 0
    //     if (player && player.deepInfo.nightProgress) {
    //         nightProgress = player.deepInfo.nightProgress
    //     }
    //     let itemInfo = doc.itemInfo || {}
    //     if (player && player.itemInfo) {
    //         itemInfo = player.itemInfo
    //     }

    //     let booming = doc.booming || 0
    //     if (player && player.townInfo.booming) {
    //         booming = player.townInfo.booming
    //     }

    //     // 判断是否测试帐号修改数据
    //     // let testCheat = player.info.cheat > 0
    //     // if (testCheat) {
    //     //     isCheat = false
    //     // }
    //     await mongodbHandle.playerDao.updateOne({
    //         _id: ObjectId(session.pID),
    //     }, {
    //         $set: {
    //             playerData: player,
    //             loginTime: time,
    //             totalPower: totalPower,
    //             mapProgressMax: mapProgressMax,
    //             deepProgress: deepProgress,
    //             weekDayIndex: weekDayIndex,
    //             nightProgress: nightProgress,
    //             phone: doc.phone || 'android',
    //             saveKey: msg.k,
    //             saveData: msg.data,
    //             itemInfo,
    //             booming,
    //         }
    //     })
    //     return { err: 0, code: 0 }
    // } else {
    //     if (doc && doc.cheat) {
    //         return {
    //             err: 0, code: 2
    //         }
    //     } else {
    //         return { err: 0, code: 1 }
    //     }
    // }
})


routes.setLogin('route', [
    ['rName', 'string'],
    ['fName', 'string'],
    ['s', "number"],
    ['data', "any"],
], async (msg, session, cb) => {
    process.send({ 'message': 'route', pid: session.pID, data: msg.data, rName: msg.rName, fName: msg.fName, s: msg.s });
    return { err: 0 }
})

routes.setLogin('setPlayerName', [
    ['name', 'string']
], async (msg, session, cb) => {
    let { name } = msg
    if (name && name.length > 0 && name.length <= 15) {
        let doc = await mongodbHandle.playerDao.findOne({
            _id: ObjectId(session.pID)
        })
        if (doc) {
            await mongodbHandle.playerDao.updateOne({
                _id: ObjectId(session.pID),
            }, {
                $set: {
                    name: name
                }
            })
            return { err: 0 }
        } else {
            return { err: 2 }
        }
    } else {
        return { err: 1 }
    }

})

routes.setLogin('savePlayerData', [
    ['keys', 'array'],
    ['datas', 'array']
], async (msg, session, cb) => {
    let { keys, datas } = msg
    let doc = await mongodbHandle.playerDao.findOne({
        _id: ObjectId(session.pID),
    })
    if (doc) {
        let setData: any = {}
        for (let i = 0; i < keys.length; i++) {
            let key = 'playerData.' + keys[i]
            let data = datas[i]
            setData[key] = data
        }
        let time = new Date().getTime()
        setData.loginTime = time
        await mongodbHandle.playerDao.updateOne({
            _id: ObjectId(session.pID),
        }, {
            $set: setData
        })
        return { err: 0 }
    } else {
        return { err: 1 }
    }
})


routes.setLogin('getMailCount', [
], async (msg, session, cb) => {
    let count = await mongodbHandle.mailDao.count({ pID: session.pID })
    return { err: 0, data: count }
})

routes.setLogin('getMail', [
], async (msg, session, cb) => {
    let docs = await mongodbHandle.mailDao.findByPageAndSort({ pID: session.pID }, { time: -1 }, 0, 40)
    return { err: 0, data: docs }
})

routes.setLogin('getMailByid', [
    ['id', 'string']
], async (msg, session, cb) => {
    let doc = await mongodbHandle.mailDao.findOne({ _id: ObjectId(msg.id) })
    if (doc) {
        await mongodbHandle.playerAndGiftDao.newAndSave2(session.pID, msg.id, [doc.items1, doc.items2])
        await mongodbHandle.mailDao.remove({ _id: ObjectId(msg.id) })
        return { err: 0, data: doc }
    } else {
        return { err: 0, code: 1 }
    }

})

routes.setLogin('delMail', [
    ['id', 'string']
], async (msg, session, cb) => {
    await mongodbHandle.mailDao.remove({ _id: ObjectId(msg.id) })
    return { err: 0 }
})


routes.setLogin('getGift', [
    ['id', 'string'],
], async (msg, session, cb) => {
    let { id } = msg
    // if (id == "pioneertest") {
    //     let doc = await mongodbHandle.giftDao.findOne({ id: id })
    //     let data = await mongodbHandle.playerAndGiftDao.findOne({ pID: session.uID, giftID: id })
    //     if (data) {
    //         return { err: 0, code: 3 }
    //     }
    //     let uData = await mongodbHandle.userDao.findOne({ _id: ObjectId(session.uID) })
    //     if (uData.registerTime > new Date('2021-6-6').getTime()) {
    //         return { err: 0, code: 5 }
    //     }
    //     await mongodbHandle.mailDao.newAndSave(session.pID, doc.name, doc.items1, doc.items2)
    //     await mongodbHandle.playerAndGiftDao.newAndSave(session.uID, id)
    //     return { err: 0 }
    // }
    let doc1 = await mongodbHandle.giftListDao.findOne({ id: id })
    if (doc1) {
        let doc2 = await mongodbHandle.giftDao.findOne({ id: doc1.giftTypeID })
        if (doc2) {
            let data = await mongodbHandle.playerAndGiftDao.findOne({ pID: session.pID, giftID: doc1.giftTypeID })
            if (data) {
                if (doc2.multiple !== true) {
                    return { err: 0, code: 3 }
                }
                // if (data.time >= moment().valueOf()) {
                //     return { err: 0, code: 4 }
                // }
            }
            await mongodbHandle.giftListDao.remove({ id: id })
            await mongodbHandle.mailDao.newAndSave(session.pID, doc2.name, doc2.items1, doc2.items2)
            if (data) {
                await mongodbHandle.playerAndGiftDao.updateOne({ pID: session.pID, giftID: doc1.giftTypeID }, {
                    $set: {
                        time: moment().hour(0).minutes(0).seconds(0).milliseconds(0).valueOf(),
                        amout: (data.amount || 1) + 1
                    }
                })
            } else {
                await mongodbHandle.playerAndGiftDao.newAndSave(session.pID, doc1.giftTypeID)
            }
            return { err: 0 }
        }
    }
    let doc = await mongodbHandle.giftDao.findOne({ id: id })
    let now = new Date().getTime()
    if (!doc || !doc.active) {
        return { err: 0, code: 1 }
    }
    if (now > doc.endtime || now < doc.starttime) {
        return { err: 0, code: 2 }
    }
    let data = await mongodbHandle.playerAndGiftDao.findOne({ pID: session.pID, giftID: id })
    if (data) {
        return { err: 0, code: 3 }
    }
    await mongodbHandle.mailDao.newAndSave(session.pID, doc.name, doc.items1, doc.items2)
    await mongodbHandle.playerAndGiftDao.newAndSave(session.pID, id)
    return { err: 0 }
})

routes.setLogin('playerModify', [
    ["value", "string"]
], async (msg, session, cb) => {
    let { value } = msg
    let doc = await mongodbHandle.playerDao.findOne({
        _id: ObjectId(session.pID),
    })
    if (doc) {
        let data: any = { modify: value }
        if (value == "init") {
            if (doc.modifyTime == moment().startOf('day').valueOf()) {
                if ((doc.modifyTimes || 0) >= 6) {
                    return { err: 0, code: 1 }
                } else {
                    data = { modify: value, modifyTime: moment().startOf('day').valueOf(), modifyTimes: (doc.modifyTimes || 0) + 1 }
                }
            } else {
                data = { modify: value, modifyTime: moment().startOf('day').valueOf(), modifyTimes: 0 }
            }
        }
        await mongodbHandle.playerDao.updateOne({
            _id: ObjectId(session.pID),
        }, {
            $set: data
        })
    }
    return { err: 0 }
})


routes.setLogin('giftBuyTims', [], async (msg, session) => {
    let doc = await mongodbHandle.playerDao.findOne({
        _id: ObjectId(session.pID),
    })
    if (doc) {
        return {
            err: 0, data: {
                giftTime: doc.giftTime || moment().startOf('day').valueOf(),
                giftBuyTims: doc.giftBuyTims || 0
            }
        }
    }
    return {
        err: 0, data: {
            giftTime: 0,
            giftBuyTims: 0
        }
    }
})
